//---------------------------------------------------------------------------------------------------------------------------------------------------------//

#include <zlib.h>

//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "CandidateDBForPGSearch.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <fstream>

#include <zlib.h>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define LENGTHLINE 500000
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
CandidateDBForPGSearch::CandidateDBForPGSearch() {
  
  this->filenameBindingProfile = new String ();
  this->filenameCATHProfile    = new String ();
  this->bindingProfiles        = new TListE <BindingInfoCathFASTAProfile> ();
  this->ligands                = new TListE <String> ();
  this->filenameOut            = new String ();
  this->toString               = new String ();
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
CandidateDBForPGSearch::CandidateDBForPGSearch(const CandidateDBForPGSearch& candidateDBForPGSearch) {
  
  this->filenameBindingProfile = new String (candidateDBForPGSearch.filenameBindingProfile);
  this->filenameCATHProfile    = new String (candidateDBForPGSearch.filenameCATHProfile);
  this->bindingProfiles        = new TListE <BindingInfoCathFASTAProfile> (candidateDBForPGSearch.bindingProfiles);
  this->ligands                = new TListE <String> (candidateDBForPGSearch.ligands);
  this->filenameOut            = new String (candidateDBForPGSearch.filenameOut);
  this->toString               = new String (candidateDBForPGSearch.toString);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
CandidateDBForPGSearch::CandidateDBForPGSearch(const CandidateDBForPGSearch* candidateDBForPGSearch) {
  
  this->filenameBindingProfile = new String (candidateDBForPGSearch->filenameBindingProfile);
  this->filenameCATHProfile    = new String (candidateDBForPGSearch->filenameCATHProfile);
  this->bindingProfiles        = new TListE <BindingInfoCathFASTAProfile> (candidateDBForPGSearch->bindingProfiles);
  this->ligands                = new TListE <String> (candidateDBForPGSearch->ligands);
  this->filenameOut            = new String (candidateDBForPGSearch->filenameOut);
  this->toString               = new String (candidateDBForPGSearch->toString);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
CandidateDBForPGSearch::~CandidateDBForPGSearch() {

  if (this->filenameBindingProfile) delete this->filenameBindingProfile;
  if (this->filenameCATHProfile)    delete this->filenameCATHProfile;
  if (this->bindingProfiles)        delete this->bindingProfiles;
  if (this->ligands)                delete this->ligands;
  if (this->filenameOut)            delete this->filenameOut;
  if (this->toString)               delete this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void CandidateDBForPGSearch::FilenameBindingProfile (String* filenameBindingProfile) {
  
  if (filenameBindingProfile) this->filenameBindingProfile->In(filenameBindingProfile);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void CandidateDBForPGSearch::FilenameCATHProfile (String* filenameCATHProfile) {
  
  if (filenameCATHProfile) this->filenameCATHProfile->In(filenameCATHProfile);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void CandidateDBForPGSearch::BindingProfiles (TListE <BindingInfoCathFASTAProfile>* bindingProfiles) {
  
  if (bindingProfiles) *(this->bindingProfiles) = *(bindingProfiles);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void CandidateDBForPGSearch::Ligands (TListE <String>* ligands) {
  
  if (ligands) *(this->ligands) = *(ligands);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void CandidateDBForPGSearch::FilenameOut (String* filenameOut) {
  
  if (filenameOut) this->filenameOut->In(filenameOut);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* CandidateDBForPGSearch::FilenameBindingProfile (void) {
  
  return this->filenameBindingProfile;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* CandidateDBForPGSearch::FilenameCATHProfile (void) {
  
  return this->filenameCATHProfile;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <BindingInfoCathFASTAProfile>* CandidateDBForPGSearch::BindingProfiles (void) {
  
  return this->bindingProfiles;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <String>* CandidateDBForPGSearch::Ligands (void) {
  
  return this->ligands;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* CandidateDBForPGSearch::FilenameOut (void) {
  
  return this->filenameOut;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::LoadData (void) {
  
  if (!this->filenameBindingProfile || !this->filenameBindingProfile->Length() ||
      !this->filenameCATHProfile    || !this->filenameCATHProfile->Length()    ||
      !this->ligands                || !this->bindingProfiles)
    return false;
  
  this->bindingProfiles->Clear();
  
  bool isGZFileBindingProfile = (this->filenameBindingProfile->Contain("gz"))?1:0;
  bool isGZFileCATHProfile    = (this->filenameCATHProfile->Contain("gz"))?1:0;

  fstream fileInBindingProfile,    fileInCATHProfile;
  gzFile  zipFileInBindingProfile, zipFileInCATHProfile;
  
  char    buffer [LENGTHLINE + 1];
  String* data = new String ();

  if (isGZFileBindingProfile) {
    zipFileInBindingProfile = gzopen (this->filenameBindingProfile->Out(), "rb9");
    if (!zipFileInBindingProfile) return false;
  }
  else {
    fileInBindingProfile.open (this->filenameBindingProfile->Out(), fstream::in);
    if (!fileInBindingProfile.is_open()) return false;
  }
  
  cout << "Loading the Binding Info..." << endl;
  
  int counter = 0;

  while (!((isGZFileBindingProfile)?gzeof(zipFileInBindingProfile):fileInBindingProfile.eof())) {
    
    if (isGZFileBindingProfile) gzgets(zipFileInBindingProfile, buffer, LENGTHLINE);
    else                        fileInBindingProfile.getline(buffer, LENGTHLINE);
    
    if (!strlen(buffer)) continue;
    
    if (buffer[0] == '>') {
      
      if (data->Length()) {
        
        BindingInfoCathFASTAProfile* newBindingInfoCathFASTAProfile = new BindingInfoCathFASTAProfile ();
        
        if (newBindingInfoCathFASTAProfile->BindingRegion()->ReadFromString(data)) {
          this->bindingProfiles->Add(newBindingInfoCathFASTAProfile);
          cout << ++counter << " - Load Domain - " << newBindingInfoCathFASTAProfile->BindingRegion()->Domain()->Out() << endl;
        }
        else 
          delete newBindingInfoCathFASTAProfile;
        
      }
      
      data->In("");
      
    }
    
    data->Add(buffer);
    data->Add("\n");
    
  }
  
  if (data->Length()) {

    BindingInfoCathFASTAProfile* newBindingInfoCathFASTAProfile = new BindingInfoCathFASTAProfile ();

    if (newBindingInfoCathFASTAProfile->BindingRegion()->ReadFromString(data)) {
      this->bindingProfiles->Add(newBindingInfoCathFASTAProfile);
      cout << ++counter << " - Load Domain - " << newBindingInfoCathFASTAProfile->BindingRegion()->Domain()->Out() << endl;
    }
    else 
      delete newBindingInfoCathFASTAProfile;

  }
  
  if (isGZFileBindingProfile) gzclose(zipFileInBindingProfile);
  else                        fileInBindingProfile.close();

  cout << "Search the Profiles..." << endl;
  
  counter = 0;

  if (isGZFileCATHProfile) {
    zipFileInCATHProfile = gzopen (this->filenameCATHProfile->Out(), "rb9");
    if (!zipFileInCATHProfile) return false;
  }
  else {
    fileInCATHProfile.open (this->filenameCATHProfile->Out(), fstream::in);
    if (!fileInCATHProfile.is_open()) return false;
  }
  
  data->In("");
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    cout << ++counter << " - Get Profile for Domain - " << currentBindingInfoCathFASTAProfile->BindingRegion()->Domain()->Out() << endl;
    
    if (isGZFileCATHProfile) gzseek(zipFileInCATHProfile, 0L, SEEK_SET);
    else                     fileInCATHProfile.seekg(0, fstream::beg);

    while (!((isGZFileCATHProfile)?gzeof(zipFileInCATHProfile):fileInCATHProfile.eof())) {

      if (isGZFileCATHProfile) gzgets(zipFileInCATHProfile, buffer, LENGTHLINE);
      else                     fileInCATHProfile.getline(buffer, LENGTHLINE);

      if (!strlen(buffer)) continue;

      data->Add(buffer);
      data->Add("\n");

      if (buffer[0] == '!') {
        
        if (data->Contain(currentBindingInfoCathFASTAProfile->BindingRegion()->Domain())) {
          
          currentBindingInfoCathFASTAProfile->CathProfile()->ReadFromString(data);
          cout << counter << " - Found Domain - " << currentBindingInfoCathFASTAProfile->BindingRegion()->Domain()->Out() << endl; 
          break;
          
        }

        data->In("");

      }

    }
    
  }

  if (isGZFileCATHProfile) gzclose(zipFileInCATHProfile);
  else                     fileInCATHProfile.close();
  
  if (data) delete data;

  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::HideDuplicated (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length())
    return false;
  
  for (long i = 0; i < this->bindingProfiles->Length(); i++) {
    
    TNode <BindingInfoCathFASTAProfile>* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetNode(i);
    
    if (currentBindingInfoCathFASTAProfile->IsHidden()) continue;
    
    for (long j = 0; j < this->bindingProfiles->Length(); j++) {
      
      if (i = j) continue;
      
      TNode <BindingInfoCathFASTAProfile>* comparedBindingInfoCathFASTAProfile = this->bindingProfiles->GetNode(j);
      
      if (!strcmp(currentBindingInfoCathFASTAProfile->Info()->CathProfile()->Sequence()->Out(), comparedBindingInfoCathFASTAProfile->Info()->CathProfile()->Sequence()->Out()))
        comparedBindingInfoCathFASTAProfile->SetHidden();
      
      if (currentBindingInfoCathFASTAProfile->Info()->CathProfile()->Sequence()->Contain(comparedBindingInfoCathFASTAProfile->Info()->CathProfile()->Sequence()))
        comparedBindingInfoCathFASTAProfile->SetHidden();
      
    }
    
  }
  
  return true;
  
}
//----------------------------------------------- ----------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteCATHProfile (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->CathProfile()->ToString()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->CathProfile()->ToString()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteProfileBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfile()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfile()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteSequencesBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSeq()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSeq()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteSecondaryPBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSS()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSS()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteSecondaryCBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSSConf()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSSConf()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteChemicalClassBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileCH()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileCH()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WritePhysicalClassBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfilePH()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfilePH()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteMetaStructureEncodeClassBindingRegion (void) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileMT()->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileMT()->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteProfileBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteSequencesBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSeqExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSeqExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteSecondaryPBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSSExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSSExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteSecondaryCBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSSConfExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileSSConfExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteChemicalClassBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileCHExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileCHExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WritePhysicalClassBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfilePHExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfilePHExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool CandidateDBForPGSearch::WriteMetaStructureEncodeClassBindingRegionExtended (int extension) {
  
  if (!this->bindingProfiles || !this->bindingProfiles->Length() ||
      !this->filenameOut     || !this->filenameOut->Length())
    return false;
  
  bool isGZFile = (this->filenameOut->Contain("gz"))?1:0;

  fstream fileOut;
  gzFile  zipFileOut;
  
  if (isGZFile) {
    zipFileOut = gzopen (this->filenameOut->Out(), "wb9");
    if (!zipFileOut) return false;
  }
  else {
    fileOut.open (this->filenameOut->Out(), fstream::out);
    if (!fileOut.is_open()) return false;
  }
  
  this->bindingProfiles->SetInitial();
  while (this->bindingProfiles->SetNext()) {
    
    BindingInfoCathFASTAProfile* currentBindingInfoCathFASTAProfile = this->bindingProfiles->GetCurrent();
    
    if (this->bindingProfiles->GetCurrentNode()->IsHidden()) continue;
    
    if (isGZFile) gzprintf(zipFileOut, "%s\n", currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileMTExtended(extension)->Out()); 
    else          fileOut << currentBindingInfoCathFASTAProfile->ToStringBindingInfoInCathProfileMTExtended(extension)->Out() << endl;
    
  }
  
  if (isGZFile) gzclose(zipFileOut);
  else          fileOut.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
CandidateDBForPGSearch CandidateDBForPGSearch::operator= (const CandidateDBForPGSearch& candidateDBForPGSearch) {
  
  this->filenameBindingProfile->In(candidateDBForPGSearch.filenameBindingProfile);
  this->filenameBindingProfile->In(candidateDBForPGSearch.filenameBindingProfile);
  
  *(this->bindingProfiles) = *(candidateDBForPGSearch.bindingProfiles);
  *(this->ligands)         = *(candidateDBForPGSearch.ligands); 
  
  this->filenameOut->In(candidateDBForPGSearch.filenameOut);
  this->toString->In(candidateDBForPGSearch.toString);

  return *this;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//

